home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / PalmGray / Src / gray.c next >
Encoding:
C/C++ Source or Header  |  1998-06-20  |  11.7 KB  |  409 lines  |  [TEXT/CWIE]

  1. /***********************************************************************
  2.  *
  3.  *    Copyright © Palm Computing 1998 -- All Rights Reserved
  4.  *
  5.  *
  6.  **********************************************************************/
  7.  
  8. #include <Pilot.h>                // all the system toolbox headers
  9. #include <SysEvtMgr.h>            //    Needed for search for EvtSysEventAvail
  10. #include <FeatureMgr.h>            //    Needed to get the ROM version
  11. #include <ScrDriverNew.h>     // to switch to grayscale mode
  12. #include "GrayRsc.h"        // application resource defines
  13. #include "GrayEdit.h"
  14.  
  15.  
  16. /***********************************************************************
  17.  * Global defines for this module
  18.  **********************************************************************/
  19. #define version20    0x02000000    // PalmOS 2.0 version number
  20. #define version30    0x03000000    // PalmOS 2.0 version number
  21.  
  22.  
  23. /***********************************************************************
  24.  * Global variables for this module
  25.  **********************************************************************/
  26. DWord gRomVersion;
  27. Boolean gSupportsGrayAPIs;
  28. Boolean gHasGrayScreen;
  29.  
  30.  
  31.  
  32. /***********************************************************************
  33.  *
  34.  * FUNCTION:    RomVersionCompatible
  35.  *
  36.  * DESCRIPTION: Check that the ROM version meets your
  37.  *              minimum requirement.  Warn if the app was switched to.
  38.  *
  39.  * PARAMETERS:  requiredVersion - minimum rom version required
  40.  *                                (see sysFtrNumROMVersion in SystemMgr.h 
  41.  *                                for format)
  42.  *              launchFlags     - flags indicating how the application was
  43.  *                                             launched.  A warning is displayed only if
  44.  *                                these flags indicate that the app is 
  45.  *                                             launched normally.
  46.  *
  47.  * RETURNED:    zero if rom is compatible else an error code
  48.  *                             
  49.  ***********************************************************************/
  50. static Err RomVersionCompatible (DWord requiredVersion, Word launchFlags)
  51. {
  52.     DWord romVersion;
  53.     
  54.     
  55.     // See if we're on in minimum required version of the ROM or later.
  56.     // The system records the version number in a feature.  A feature is a
  57.     // piece of information which can be looked up by a creator and feature
  58.     // number.
  59.     FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
  60.     if (romVersion < requiredVersion)
  61.         {
  62.         // If the user launched the app from the launcher, explain
  63.         // why the app shouldn't run.  If the app was contacted for something
  64.         // else, like it was asked to find a string by the system find, then
  65.         // don't bother the user with a warning dialog.  These flags tell how
  66.         // the app was launched to decided if a warning should be displayed.
  67.         if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
  68.             (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
  69.             {
  70.             FrmAlert (RomIncompatibleAlert);
  71.         
  72.             // Pilot 1.0 will continuously relaunch this app unless we switch to 
  73.             // another safe one.  The sysFileCDefaultApp is considered "safe".
  74.             if (romVersion < 0x02000000)
  75.                 {
  76.                 Err err;
  77.                 
  78.                 AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
  79.                 }
  80.             }
  81.         
  82.         return (sysErrRomIncompatible);
  83.         }
  84.  
  85.     return 0;
  86. }
  87.  
  88. /***********************************************************************
  89.  *
  90.  * FUNCTION:     StartApplication
  91.  *
  92.  * DESCRIPTION:  This routine sets up the initial state of the application.
  93.  *               It opens the application's database and sets up global variables. 
  94.  *
  95.  * PARAMETERS:   None.
  96.  *
  97.  * RETURNED:     true if error (database couldn't be created)
  98.  *
  99.  ***********************************************************************/
  100. static Boolean StartApplication(void)
  101. {
  102.     DWord depth;      // Apps needing B/W should use 1, grayscale apps use 2
  103.     DWord supported;
  104.     
  105.     FtrGet(sysFtrCreator, sysFtrNumROMVersion, &gRomVersion);
  106.     
  107.     gHasGrayScreen=0; // be pessimistic.  Pilots and PalmPilots actually can do gray, 
  108.                             // but that requires hacking
  109.     
  110. // temporary
  111. // gRomVersion=version20;  
  112. // temporary
  113.  
  114.     if (gRomVersion>=version30) {
  115.         gSupportsGrayAPIs=1;  // we have APIs that support gray. Let's switch up if possible
  116.  
  117.         ScrDisplayMode(scrDisplayModeGetSupportedDepths, NULL, NULL, &supported, NULL);
  118.         supported = supported >> 1; // we don't care about black-and-white support
  119.         if (supported) {    // if it supports any non-bw mode
  120.             gHasGrayScreen=1;
  121.  
  122.             // switch to the lowest depth non-bw mode the screen supports
  123.             depth = 2;
  124.             while (!(supported & 0x01)) {
  125.                 depth << 1;
  126.                 supported = supported >> 1;
  127.             }
  128.             // should check the error return from this...
  129.             ScrDisplayMode(scrDisplayModeSet, NULL, NULL, &depth, NULL);
  130.         }
  131.     } else
  132.         gSupportsGrayAPIs=0;
  133.  
  134.     return false;
  135. }
  136.  
  137. /***********************************************************************
  138.  *
  139.  * FUNCTION:    StopApplication
  140.  *
  141.  * DESCRIPTION: This routine closes the application's database
  142.  *              and saves the current state of the application.
  143.  *
  144.  * PARAMETERS:  nothing
  145.  *
  146.  * RETURNED:    nothing
  147.  *
  148.  ***********************************************************************/
  149. static void StopApplication(void)
  150. {
  151.     // Close all open forms to allow their frmCloseEvent handlers
  152.     // to execute.  An appStopEvent doesn't send frmCloseEvents.
  153.     // FrmCloseAllForms will send all opened forms a frmCloseEvent.
  154.     FrmCloseAllForms ();
  155.  
  156. }
  157.  
  158.  
  159. /***********************************************************************
  160.  *
  161.  * FUNCTION:    GetObjectPtr
  162.  *
  163.  * DESCRIPTION: This routine returns a pointer to an object in the active form.
  164.  *
  165.  * PARAMETERS:  objectID - id of the object
  166.  *
  167.  * RETURNED:    pointer to the object's data structure
  168.  *
  169.  ***********************************************************************/
  170. static VoidPtr GetObjectPtr(Int objectID)
  171. {
  172.     FormPtr frm;
  173.     
  174.     frm = FrmGetActiveForm();
  175.     return(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, objectID)));
  176. }
  177.  
  178. /***********************************************************************
  179.  *
  180.  * FUNCTION:        MainViewInit
  181.  *
  182.  * DESCRIPTION:    Initializes the main form and the list object.
  183.  *
  184.  * PARAMETERS:        frm - pointer to the main form.
  185.  *
  186.  * RETURNED:        Nothing.
  187.  *
  188.  ***********************************************************************/
  189. static void MainViewInit(void)
  190. {
  191.     FormPtr            frm;
  192.  
  193.  
  194.     // Get a pointer to the main form.
  195.     frm = FrmGetActiveForm();
  196.     
  197.     // Draw the form.
  198.     FrmDrawForm(frm);
  199. }
  200.  
  201. /***********************************************************************
  202.  *
  203.  * FUNCTION:        PtInGadget
  204.  *
  205.  * RETURNED:        True if the point is in the bounds of the gadget
  206.  *
  207.  ***********************************************************************/
  208. static Boolean PtInGadget(Word obj, SWord x, SWord y, FormPtr frm)
  209. {
  210.     RectangleType r;
  211.     FrmGetObjectBounds (frm, FrmGetObjectIndex (frm, obj), &r);
  212.     return (RctPtInRectangle (x, y, &r));
  213. }
  214.  
  215. /***********************************************************************
  216.  *
  217.  * FUNCTION:        MainViewHandleEvent
  218.  *
  219.  * DESCRIPTION:    Handles processing of events for the “main” form.
  220.  *
  221.  * PARAMETERS:        event    - the most recent event.
  222.  *
  223.  * RETURNED:        True if the event is handled, false otherwise.
  224.  *
  225.  ***********************************************************************/
  226. static Boolean MainViewHandleEvent(EventPtr event)
  227. {
  228.     Boolean        handled = false;
  229.     RectangleType r;
  230.     FormPtr        frm;
  231.  
  232.  
  233.     switch (event->eType)
  234.         {
  235.        case ctlSelectEvent:  // A control button was pressed and released.
  236.            if (event->data.ctlEnter.controlID == 0) {
  237.                 handled = true;
  238.             }
  239.             break;
  240.         
  241.         case penDownEvent:
  242.         case penMoveEvent:
  243.             frm = FrmGetActiveForm ();
  244.  
  245.             if (PtInGadget(GrayMainPixelGadget, event->screenX, event->screenY, frm))
  246.                 HitPixel(event->screenX, event->screenY);
  247.  
  248.             else if (PtInGadget(GrayMainBigBWGadget, event->screenX, event->screenY, frm))
  249.                 SaveAndSwitch(GrayMainBigBWGadget);
  250.  
  251.             else if (PtInGadget(GrayMainBigGrayGadget, event->screenX, event->screenY, frm))
  252.                 SaveAndSwitch(GrayMainBigGrayGadget);
  253.  
  254.             else if (PtInGadget(GrayMainSmallBWGadget, event->screenX, event->screenY, frm))
  255.                 SaveAndSwitch(GrayMainSmallBWGadget);
  256.  
  257.             else if (PtInGadget(GrayMainSmallGrayGadget, event->screenX, event->screenY, frm))
  258.                 SaveAndSwitch(GrayMainSmallGrayGadget);
  259.  
  260.  
  261.             else if (PtInGadget(GrayMainPen0Gadget, event->screenX, event->screenY, frm))
  262.                 SetPenTo(0);
  263.             else if (PtInGadget(GrayMainPen1Gadget, event->screenX, event->screenY, frm))
  264.                 SetPenTo(1);
  265.             else if (PtInGadget(GrayMainPen2Gadget, event->screenX, event->screenY, frm))
  266.                 SetPenTo(2);
  267.             else if (PtInGadget(GrayMainPen3Gadget, event->screenX, event->screenY, frm))
  268.                 SetPenTo(3);
  269.             break;
  270.       
  271.  
  272.           case frmUpdateEvent:
  273.               DrawEditorAndDisplays();
  274.               break;
  275.           
  276.           case frmOpenEvent:
  277.             MainViewInit();
  278.             InitGrayEdit();
  279.             DrawEditorAndDisplays();
  280.             handled = true;
  281.             break;
  282.             
  283.         }
  284.     return(handled);
  285. }
  286.  
  287.  
  288. /***********************************************************************
  289.  *
  290.  * FUNCTION:    ApplicationHandleEvent
  291.  *
  292.  * PARAMETERS:  event - a pointer to an EventType structure
  293.  *
  294.  * RETURNED:    True if the event has been handled and should not be
  295.  *                        passed to a higher level handler.
  296.  *
  297.  ***********************************************************************/
  298. static Boolean ApplicationHandleEvent(EventPtr event)
  299. {
  300.     FormPtr    frm;
  301.     Int        formId;
  302.     Boolean    handled = false;
  303.  
  304.     if (event->eType == frmLoadEvent)
  305.         {
  306.         // Load the form resource specified in the event then activate the form.
  307.         formId = event->data.frmLoad.formID;
  308.         frm = FrmInitForm(formId);
  309.         FrmSetActiveForm(frm);
  310.  
  311.         // Set the event handler for the form.  The handler of the currently 
  312.         // active form is called by FrmDispatchEvent each time it receives an event.
  313.         switch (formId)
  314.             {
  315.             case GrayMainForm:
  316.                 FrmSetEventHandler(frm, MainViewHandleEvent);
  317.                 break;
  318.         
  319.             }
  320.         handled = true;
  321.         }
  322.     
  323.     return handled;
  324. }
  325.  
  326.  
  327. /***********************************************************************
  328.  *
  329.  * FUNCTION:        EventLoop
  330.  *
  331.  * DESCRIPTION:    A simple loop that obtains events from the Event
  332.  *                        Manager and passes them on to various applications and
  333.  *                        system event handlers before passing them on to
  334.  *                        FrmDispatchEvent for default processing.
  335.  *
  336.  * PARAMETERS:        None.
  337.  *
  338.  * RETURNED:        Nothing.
  339.  *
  340.  ***********************************************************************/
  341. static void EventLoop(void)
  342. {
  343.     EventType    event;
  344.     Word            error;
  345.     
  346.     do
  347.         {
  348.         // Get the next available event.
  349.         EvtGetEvent(&event, evtWaitForever);
  350.         
  351.         // Give the system a chance to handle the event.
  352.         if (! SysHandleEvent(&event))
  353.  
  354.             // Give the menu bar a chance to update and handle the event.    
  355.             if (! MenuHandleEvent(0, &event, &error))
  356.  
  357.                 // Give the application a chance to handle the event.
  358.                 if (! ApplicationHandleEvent(&event))
  359.  
  360.                     // Let the form object provide default handling of the event.
  361.                     FrmDispatchEvent(&event);
  362.         }
  363.     while (event.eType != appStopEvent);
  364. }
  365.  
  366.  
  367. /***********************************************************************
  368.  *
  369.  * FUNCTION:        PilotMain
  370.  *
  371.  * DESCRIPTION:    This function is the equivalent of a main() function
  372.  *                        under standard “C”.  It is called by the Emulator to begin
  373.  *                        execution of this application.
  374.  *
  375.  * PARAMETERS:        cmd - command specifying how to launch the application.
  376.  *                        cmdPBP - parameter block for the command.
  377.  *                        launchFlags - flags used to configure the launch.            
  378.  *
  379.  * RETURNED:        Any applicable error codes.
  380.  *
  381.  ***********************************************************************/
  382. DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
  383. {
  384.     Word error;
  385.     
  386.     error = RomVersionCompatible (version20, launchFlags);
  387.     if (error)
  388.         return error;
  389.  
  390.     // Check for a normal launch.
  391.     if (cmd == sysAppLaunchCmdNormalLaunch)
  392.         {
  393.         // Initialize the application's global variables and database.
  394.         if (!StartApplication())
  395.             {
  396.             // Start the first form.
  397.             FrmGotoForm(GrayMainForm);
  398.                 
  399.             // Start the event loop.
  400.             EventLoop();
  401.             
  402.             // Clean up before exiting the applcation.
  403.             StopApplication();
  404.             }
  405.         }
  406.         
  407.     return 0;
  408. }
  409.